package com.web.crawler.compare;

import java.io.*;
import java.nio.file.*;
import java.util.*;
import java.util.stream.*;

public class DocumentComparator {
    private List<String> documents;
    private List<String> documentNames;
    private Map<String, Integer> vocabulary;
    private Map<String, Double> idfMap;
    private List<double[]> tfIdfVectors;


    public List<double[]> getTfIdfVectors() {
        return tfIdfVectors;
    }

    public List<String> getDocumentContents() {
        return documents;
    }
    public DocumentComparator(String folderPath) throws IOException {
        // 读取文档
        this.documentNames = new ArrayList<>();
        this.documents = new ArrayList<>();

        try (Stream<Path> paths = Files.walk(Paths.get(folderPath))) {
            paths.filter(Files::isRegularFile)
                    .forEach(path -> {
                        try {
                            String fileName = path.getFileName().toString();
                            String content = new String(Files.readAllBytes(path));

                            documentNames.add(fileName);
                            documents.add(content);
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    });
        }

        // 构建词汇表和IDF
        this.vocabulary = Vectorizer.buildVocabulary(documents);
        this.idfMap = Vectorizer.calculateIdf(documents, vocabulary);
        // 为所有文档计算TF-IDF向量
        this.tfIdfVectors = documents.stream()
                .map(doc -> Vectorizer.toTfIdfVector(doc, vocabulary, idfMap))
                .collect(Collectors.toList());
    }

    // 比较两个文档的相似度
    public void compareTwoDocuments(int doc1Index, int doc2Index) {
        if (doc1Index < 0 || doc1Index >= documents.size() ||
                doc2Index < 0 || doc2Index >= documents.size()) {
            //throw new IllegalArgumentException("Invalid document index");
            throw new IllegalArgumentException("非法文档索引");
        }

        double similarity = SimilarityCalculator.cosineSimilarity(
                tfIdfVectors.get(doc1Index),
                tfIdfVectors.get(doc2Index));

        System.out.println("对比结果:");
        System.out.println("文档 1：" + documentNames.get(doc1Index));
        System.out.println("文档 2: " + documentNames.get(doc2Index));
        System.out.printf("相似度: %.4f\n", similarity);
        System.out.println("----------------------");

        // 打印部分内容
        System.out.println("文档 1 的内容(前两百个字符):");
        System.out.println(truncate(documents.get(doc1Index), 200));
        System.out.println("----------------------");
        System.out.println("文档 2 的内容(前两百个字符):");
        System.out.println(truncate(documents.get(doc2Index), 200));
        System.out.println("======================");
    }

    // 查找与指定文档最相似的文档
    public void findMostSimilarDocument(int targetDocIndex) {
        if (targetDocIndex < 0 || targetDocIndex >= documents.size()) {
            throw new IllegalArgumentException("非法文档索引");
        }

        double maxSimilarity = -1;
        int mostSimilarIndex = -1;

        for (int i = 0; i < tfIdfVectors.size(); i++) {
            if (i == targetDocIndex) continue;

            double similarity = SimilarityCalculator.cosineSimilarity(
                    tfIdfVectors.get(targetDocIndex),
                    tfIdfVectors.get(i));

            if (similarity > maxSimilarity) {
                maxSimilarity = similarity;
                mostSimilarIndex = i;
            }
        }

        System.out.println("文档: " + documentNames.get(targetDocIndex));
        System.out.println("最相似的文档是: " + documentNames.get(mostSimilarIndex));
        System.out.printf("相似度: %.4f\n", maxSimilarity);
        System.out.println("----------------------");

        // 打印部分内容
        System.out.println("指定的文档(前 200 个字符):");
        System.out.println(truncate(documents.get(targetDocIndex), 200));
        System.out.println("----------------------");
        System.out.println("最相似的文档(前 200 个字符)");
        System.out.println(truncate(documents.get(mostSimilarIndex), 200));
        System.out.println("======================");
    }

    // 文档查重 - 找出相似度超过阈值的文档对
    public void findDuplicateDocuments(double threshold) {
        System.out.println("搜索重复的文档(相似度大于 " + threshold + " )");
        System.out.println("=============================================");

        for (int i = 0; i < documents.size(); i++) {
            for (int j = i + 1; j < documents.size(); j++) {
                double similarity = SimilarityCalculator.cosineSimilarity(
                        tfIdfVectors.get(i),
                        tfIdfVectors.get(j));

                if (similarity > threshold) {
                    System.out.println("相似的文档:");
                    System.out.println("1. " + documentNames.get(i));
                    System.out.println("2. " + documentNames.get(j));
                    System.out.printf("相似度: %.4f\n", similarity);
                    System.out.println("----------------------");

                    // 打印部分内容
                    System.out.println("文档 1 的内容(前两百个字符):");
                    System.out.println(truncate(documents.get(i), 200));
                    System.out.println("----------------------");
                    System.out.println("文档 2 的内容(前两百个字符):");
                    System.out.println(truncate(documents.get(j), 200));
                    System.out.println("======================");
                }
            }
        }
    }

    private String truncate(String text, int length) {
        if (text.length() <= length) {
            return text;
        }
        return text.substring(0, length) + "...";
    }

    public List<String> getDocumentNames() {
        return documentNames;
    }
}